#include<bits/stdc++.h>
#define int long long
#define N 50005
#define mid ((l+r)>>1)
using namespace std;
int n,m;
int fa[N],a[N];
int ans[N];
int siz[N],dep[N],son[N],top[N];
int len[N],id[N];
int t[N<<2],lazy[N<<2],ls[N<<2],rs[N<<2];
int cnt,rt[N];
int w=1,B;
vector<int> g[N];
vector<int> c[N];
struct Node{
    int l,r,id;
}q[N];
bool cmp(Node x,Node y){
    if(x.l/B!=y.l/B) return x.l<y.l;
    if(x.r!=y.r) return x.r<y.r;
    return x.id<y.id;
}
void dfs1(int x,int f){
    dep[x]=dep[f]+1;
    siz[x]=1;
    for(int v:g[x]){
        dfs1(v,x);
        siz[x]+=siz[v];
        if(siz[v]>siz[son[x]]) son[x]=v;
    }
}
void dfs2(int x,int topf){
    top[x]=topf;
    id[x]=++len[topf];
    c[topf].push_back(x);
    if(son[x]) dfs2(son[x],topf);
    for(int v:g[x]) if(!top[v]) dfs2(v,v);
}
inline void pushup(int x){
    t[x]=t[ls[x]]+t[rs[x]];
}
inline void down(int &x,int k,int len){
    if(!x) x=++cnt;
    t[x]+=k*len;
    lazy[x]+=k;
}
inline void pushdown(int x,int l,int r){
    if(!lazy[x]) return;
    down(ls[x],lazy[x],mid-l+1);
    down(rs[x],lazy[x],r-mid);
    lazy[x]=0;
}
void update(int &x,int l,int r,int L,int R,int k){
    if(L>R) return;
    if(!x) x=++cnt;
    if(L<=l&&r<=R){down(x,k,r-l+1);return;}
    pushdown(x,l,r);
    if(L<=mid) update(ls[x],l,mid,L,R,k);
    if(R>mid) update(rs[x],mid+1,r,L,R,k);
    pushup(x);
}
int query(int x,int l,int r,int L,int R){
    if(!x) return 0;
    if(L>R) return 0;
    if(L<=l&&r<=R) return t[x];
    pushdown(x,l,r);
    int res=0;
    if(L<=mid) res+=query(ls[x],l,mid,L,R);
    if(R>mid) res+=query(rs[x],mid+1,r,L,R);
    return res;
}
int Query(int x,int l,int r){
    if(l==r) return l;
    pushdown(x,l,r);
    if(t[rs[x]]<=0) return Query(ls[x],l,mid);
    return Query(rs[x],mid+1,r);
}
inline void Update(int x,int y,int k){
    if(!x) return;
    while(top[x]!=top[y]){
        update(rt[top[x]],1,len[top[x]],1,id[x],k);
        x=fa[top[x]];
    }
    update(rt[top[x]],1,len[top[x]],id[y],id[x],k);
}
#undef mid
inline void add(int x){
    int y=x;
    while(1){
        if(t[rt[top[y]]]) break;
        y=fa[top[y]];
    }
    int l=1,r=id[y],p=1,W=query(rt[top[y]],1,len[top[y]],1,id[y]);
    while(l<=r){
        int mid=(l+r)/2;
        if(query(rt[top[y]],1,len[top[y]],1,id[mid])==W) p=mid,r=mid-1;
        else l=mid+1;
    }
    y=c[top[y]][p-1];
    if(query(rt[top[y]],1,len[top[y]],id[y],id[y])==1) w++;
    if(query(rt[top[x]],1,len[top[x]],id[x],id[x])<=1) w++;
    update(rt[top[x]],1,len[top[x]],id[x],id[x],1);
    Update(x,y,1);
}
inline void del(int x){
    update(rt[top[x]],1,len[top[x]],id[x],id[x],-1);
    Update(x,1,-1);
    int y=x;
    while(1){
        if(t[rt[top[y]]]) break;
        y=fa[top[y]];
    }
    int l=1,r=id[y],p=1,W=query(rt[top[y]],1,len[top[y]],1,id[y]);
    while(l<=r){
        int mid=(l+r)/2;
        if(query(rt[top[y]],1,len[top[y]],1,id[mid])==W) p=mid,r=mid-1;
        else l=mid+1;
    }
    y=c[top[y]][p-1];
    Update(fa[y],1,1);
    if(query(rt[top[y]],1,len[top[y]],id[y],id[y])==1) w--;
    if(query(rt[top[x]],1,len[top[x]],id[x],id[x])<=1) w--;
}
signed main(){
    freopen("escape.in","r",stdin);
    freopen("escape.out","w",stdout);
    scanf("%lld %lld",&n,&m);
    for(int i=2;i<=n;i++){
        scanf("%lld",&fa[i]);
        g[fa[i]].push_back(i);
    }
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=m;i++){
        scanf("%lld %lld",&q[i].l,&q[i].r);
        q[i].id=i;
    }
    B=sqrt(n);
    sort(q+1,q+m+1,cmp);
    dfs1(1,0);
    dfs2(1,1);
    int L=1,R=1;
    Update(a[1],1,1);
    update(rt[top[1]],1,len[top[1]],id[1],id[1],1);
    for(int i=1;i<=m;i++){
        while(R<q[i].r) add(a[++R]);
        while(L>q[i].l) add(a[--L]);
        while(R>q[i].r) del(a[R--]);
        while(L<q[i].l) del(a[L++]);
        ans[q[i].id]=w;
    }
    for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
    return 0;
}